mod brick;
pub mod buffer;
mod context;
pub mod material;
pub mod math;
pub mod mesh;
#[cfg(feature = "misc")]
pub mod misc;
mod pixmap;
pub mod renderer;
pub mod shader;

use cgmath::{vec4, Vector4};

pub use brick::*;
pub use context::*;
pub use material::Material;
pub use pixmap::*;

pub const COLOR_TRANSPARENT: Vector4<f32> = vec4(0.0, 0.0, 0.0, 0.0);
pub const COLOR_BLACK: Vector4<f32> = vec4(0.0, 0.0, 0.0, 1.0);
pub const COLOR_BLUE: Vector4<f32> = vec4(0.0, 0.0, 1.0, 1.0);
pub const COLOR_GREEN: Vector4<f32> = vec4(0.0, 1.0, 0.0, 1.0);
pub const COLOR_CYAN: Vector4<f32> = vec4(0.0, 1.0, 1.0, 1.0);
pub const COLOR_RED: Vector4<f32> = vec4(1.0, 0.0, 0.0, 1.0);
pub const COLOR_PURPLE: Vector4<f32> = vec4(1.0, 0.0, 1.0, 1.0);
pub const COLOR_YELLOW: Vector4<f32> = vec4(1.0, 1.0, 0.0, 1.0);
pub const COLOR_WHITE: Vector4<f32> = vec4(1.0, 1.0, 1.0, 1.0);

pub trait AsBytes {
    fn as_bytes(&self) -> &[u8];
}

impl<T: Sized + Copy + Clone> AsBytes for T {
    fn as_bytes(&self) -> &[u8] {
        unsafe {
            std::slice::from_raw_parts(
                self as *const Self as *const u8,
                std::mem::size_of::<Self>(),
            )
        }
    }
}

impl<D: AsBytes> AsBytes for [D] {
    fn as_bytes(&self) -> &[u8] {
        unsafe { std::slice::from_raw_parts(self.as_ptr() as _, std::mem::size_of_val(self)) }
    }
}

pub trait Vertex: AsBytes + Copy + Clone {
    const ATTRS: &'static [wgpu::VertexAttribute];
    fn layout() -> wgpu::VertexBufferLayout<'static>
    where
        Self: Sized,
    {
        wgpu::VertexBufferLayout {
            array_stride: std::mem::size_of::<Self>() as u64,
            step_mode: wgpu::VertexStepMode::Vertex,
            attributes: Self::ATTRS,
        }
    }
}
